package com.anXin.article.service.impl;


import com.alibaba.fastjson.JSON;
import com.anXin.article.mapper.ArticleChannelMapper;
import com.anXin.article.mapper.ArticleMapper;
import com.anXin.article.mapper.ReplyMapper;
import com.anXin.article.service.*;
import com.anXin.common.constants.ArticleConstants;
import com.anXin.model.article.pojos.*;
import com.anXin.model.common.dtos.ResponseResult;
import com.anXin.model.common.dtos.article.ServiceException;
import com.anXin.model.common.enums.AppHttpCodeEnum;
import com.anXin.model.search.vos.SearchArticleVo;
import com.anXin.model.user.pojos.User;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import utils.thread.AppThreadLocalUtil;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

import static com.anXin.model.common.dtos.article.ServiceCode.ERROR;
import static com.anXin.model.common.dtos.article.ServiceCode.NO_POWER;

@Slf4j
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private ArticleChannelService articleChannelService;


    @Resource
    private ReplyService replyService;
    @Resource
    private CollectService collectService;

    @Resource
    private LikeService likeService;

    @Resource
    private ArticleConfigService articleConfigService;

    @Resource
    private ReplyMapper replyMapper;

    @Resource
    private ArticleChannelMapper articleChannelMapper;
    @Override
    public ResponseResult<List<Article>> selectAllArticle() {
        List<Article> articles = query().eq("status",9).list();
        List<Article> list = articles.stream().map(article -> {
            article.setLikeCount(likeService.likeCount(article.getId()));
            article.setCollectionCount(collectService.collectCount(article.getId()));
            article.setIsLike(likeService.isLike(article.getId()));
            article.setIsCollection(collectService.isCollect(article.getId()));
            return article;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult<List<Article>> selectArticleByChannel(Long id) {
        List<Article> articles = query().eq("status",9).eq("channel_id", id).list();
        List<Article> list = articles.stream().map(article -> {
            article.setLikeCount(likeService.likeCount(article.getId()));
            article.setCollectionCount(collectService.collectCount(article.getId()));
            article.setIsLike(likeService.isLike(article.getId()));
            article.setIsCollection(collectService.isCollect(article.getId()));
            return article;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(list);
    }

    @Override
    public void DeleteById(Long id) {
        log.info("开始处理文章删除业务，参数为{}",id);

        User user = AppThreadLocalUtil.getUser();
        if(user==null){
            throw new ServiceException(ERROR,"请先登录");
        }
        if(articleMapper.selectById(id)==null){
            throw new ServiceException(ERROR,"文章不存在");
        }
        if (articleMapper.selectById(id).getAuthorId().equals (user.getId())){
            QueryWrapper<Reply> wrapper = new QueryWrapper();
            List<Reply> lists = replyMapper.selectList(wrapper.eq("article_id",id));
            if (lists!=null){
                for (Reply reply : lists){
                    replyService.deleteReply(reply.getId());
                }
            }
            int row =  articleMapper.deleteById(id);
            if (row!=1){
                throw new ServiceException(ERROR,"删除文章失败，服务器繁忙");
            }
        } else {
            throw new ServiceException(NO_POWER,"您没有权限");
        }
    }

    @Override
    public void deleteArticleById(Long id) {
        List<Reply> lists= replyService.query().eq("article_id",id).list();
        if (lists!=null){
            for (Reply reply :lists){
                replyService.deleteReply(reply.getId());
            }
        }
        List<Collect> collects=collectService.query().eq("article_id",id).list();
        if (collects!=null){
            collectService.removeByIds(collects);
        }
        List<Like> likes=likeService.query().eq("article_id",id).list();
        if (likes!=null){
            likeService.removeByIds(likes);
        }
        ArticleConfig articleConfig = articleConfigService.query().eq("article_id",id).one();
        articleConfigService.removeById(articleConfig.getId());
    }



    @Override
    public ResponseResult saveArticle(Article article) {
        //检查参数
        if (article==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //判断是否存在id
        if (article.getId()==null){
            //不存在id 保存 文章 文章配置 文章内容
            save(article);
            //保存配置
            ArticleConfig articleConfig = new ArticleConfig(article.getId());
            articleConfigService.save(articleConfig);

        }else {
            //存在id 修改 文章 文字内容
            updateById(article);

        }


//发送消息，创建索引
        createArticleESIndex(article,article.getContent());

        //结果返回文章id
        return ResponseResult.okResult(article.getId());
    }

    @Override
    public ResponseResult<List<ArticleChannel>> selectChannel() {
        List<ArticleChannel> list = articleChannelMapper.selectList(null);
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult<List<Article>> selectMyArticle() {
        List<Article> articles = query().eq("author_id", AppThreadLocalUtil.getUser().getId()).list();
        List<Article> list = articles.stream().map(article -> {
            article.setLikeCount(likeService.likeCount(article.getId()));
            article.setCollectionCount(collectService.collectCount(article.getId()));
            article.setIsLike(likeService.isLike(article.getId()));
            article.setIsCollection(collectService.isCollect(article.getId()));
            return article;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult<List<Article>> selectMyArticleToBeReviewed() {
        List<Article> articles = query().eq("author_id", AppThreadLocalUtil.getUser().getId()).le("status",1).list();
        List<Article> list = articles.stream().map(article -> {
            article.setLikeCount(likeService.likeCount(article.getId()));
            article.setCollectionCount(collectService.collectCount(article.getId()));
            article.setIsLike(likeService.isLike(article.getId()));
            article.setIsCollection(collectService.isCollect(article.getId()));
            return article;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult<List<Article>> selectMyArticleByAudited() {
        List<Article> articles = query().eq("author_id", AppThreadLocalUtil.getUser().getId()).ge("status",2).list();
        List<Article> list = articles.stream().map(article -> {
            article.setLikeCount(likeService.likeCount(article.getId()));
            article.setCollectionCount(collectService.collectCount(article.getId()));
            article.setIsLike(likeService.isLike(article.getId()));
            article.setIsCollection(collectService.isCollect(article.getId()));
            return article;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult<List<Article>> selectMyArticleByUnPublish() {
        List<Article> articles = query().eq("author_id", AppThreadLocalUtil.getUser().getId()).eq("status",8).list();
        List<Article> list = articles.stream().map(article -> {
            article.setLikeCount(likeService.likeCount(article.getId()));
            article.setCollectionCount(collectService.collectCount(article.getId()));
            article.setIsLike(likeService.isLike(article.getId()));
            article.setIsCollection(collectService.isCollect(article.getId()));
            return article;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult<List<Article>> selectMyArticleByReleased() {
        List<Article> articles = query().eq("author_id", AppThreadLocalUtil.getUser().getId()).eq("status",9).list();
        List<Article> list = articles.stream().map(article -> {
            article.setLikeCount(likeService.likeCount(article.getId()));
            article.setCollectionCount(collectService.collectCount(article.getId()));
            article.setIsLike(likeService.isLike(article.getId()));
            article.setIsCollection(collectService.isCollect(article.getId()));
            return article;
        }).collect(Collectors.toList());
        return ResponseResult.okResult(list);
    }

    @Resource
    private KafkaTemplate<String,String> kafkaTemplate;

    /**
     * 发送消息创建索引
     */
    private void createArticleESIndex(Article article, String content) {
        SearchArticleVo vo = new SearchArticleVo();
        BeanUtils.copyProperties(article,vo);
        vo.setContent(content);
        vo.setLayout((Short)  article.getLayout());
        kafkaTemplate.send(ArticleConstants.ARTICLE_ES_SYNC_TOPIC, JSON.toJSONString(vo));
    }
}
